#include<iostream>
#include<string>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <ctime>
#include <openssl/sha.h>
#include <cmath>
#include "sv_node.hpp"
#include "my570list.hpp"
#include "cs570.h"

//extern FILE *Log;
extern struct timeval tim;
extern string extfile;
extern string LogLocation;
//extern FILE* status;
extern char* HomeDir1;
extern char* LogFilename1;
extern char* UOIDstr;
extern char hostname[512];
//extern My570List* EventQ;
extern My570List* SocketList;
extern ini_info* i1;

extern pthread_mutex_t SocketList_lock;
extern pthread_mutex_t EventQ_lock;
extern pthread_mutex_t GlobalList_lock;
extern pthread_cond_t EventQ_cv;
extern pthread_mutex_t PrintLock;
extern pthread_mutex_t DBaseLock;
extern pthread_mutex_t NeighborList_lock; //= PTHREAD_MUTEX_INITIALIZER;
extern pthread_mutex_t status_lock;
extern pthread_mutex_t nam_lock;
extern pthread_mutex_t log_lock;


My570List* DBase = new My570List();
My570List* nam = new My570List();
extern My570List* NeighborList;

extern list<GlobalList_Elem*> GlobalList;
int Catch;    
extern int counter; 
extern unsigned char *node_instance_id;
extern bool Duplicate;
extern int dupGlobal;
using namespace std;

void *Process_func(void *threadarg)
{
	
	
	//----------------- READING ALL BUT 1 BYTE
	int numBytes=0;
	int mySocket=0;
	mySocket = (int)threadarg;
	unsigned char *readBuf = new unsigned char[512];
	for (int it3 = 0;it3<45 ;it3++ )
		{
			if ((numBytes = read(mySocket,&readBuf[it3], 1))==-1)
			{
			//	perror("read");
			}
		}

    //----------------------------------------

	//--------------------- READING INTO FLOOD ELEM AND PUTTING INTO CORRECSPONDING EVENT QUEUE
	Flood_Elem *fd_obj = new Flood_Elem();
	fd_obj->MessageType = JNRQ;
	fd_obj->UOID = new unsigned char[20];
	fd_obj->respUOID = new unsigned char[20];
	memcpy(fd_obj->UOID,&readBuf[0],20);  
	memcpy(&(fd_obj->TTL),&readBuf[20],1);
	memcpy(&(fd_obj->HostLocation),&readBuf[26],4);
	memcpy(&(fd_obj->Port),&readBuf[30],2);
	fd_obj->TTL = (unsigned char)(((int)fd_obj->TTL)- 1);

//---------------------------------------------- RESET----------------------------------------------------//
	pthread_mutex_lock(&log_lock);
	FILE *Log1 = fopen(LogLocation.c_str(),"a");
	if(Log1==NULL)
	{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
	}else{
	gettimeofday(&tim,NULL);
	fprintf(Log1,"r %10ld.%03d nunki.usc.edu_%d JNRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),fd_obj->Port,(int)(fd_obj->TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log1,"%02x",(fd_obj->UOID)[pr]);}
	fprintf(Log1," %d nunki.usc.edu\n",fd_obj->Port);
	fflush(Log1);
	}
	fclose(Log1);
	pthread_mutex_unlock(&log_lock);
	//---------------------------------------------------------------------------------------------------------//


	list<Flood_Elem*>* EventQ = new list<Flood_Elem*>;
	GlobalList_Elem *Gelem = new GlobalList_Elem();
	Gelem->UOID = new unsigned char[20];
	Gelem->ListP = *EventQ;
	Gelem->Port =  fd_obj->Port;
	Gelem->Temp = 1;
	Gelem->Socket=mySocket;
	memcpy(Gelem->UOID,fd_obj->UOID,20);

	pthread_mutex_lock(&GlobalList_lock);
	GlobalList.push_back(Gelem);
	dupGlobal = eval_Global();
	pthread_mutex_unlock(&GlobalList_lock);
	
	list<GlobalList_Elem*>::iterator ite;


	//----------------------------------------------------------------------------------------
	list<GlobalList_Elem*>::iterator it;
	pthread_mutex_lock(&GlobalList_lock);
	for (it =GlobalList.begin();it!=GlobalList.end();it++ )
	{
		GlobalList_Elem *g1 = NULL;
		g1 = (GlobalList_Elem*) (*it);
		if ((*it)!=NULL)
		{
			if (g1->Temp != 1 && g1->Temp != 2)
			{
				//cout<<"Flooding to "<<g1->Port<<endl;
			pthread_mutex_lock(&g1->EventQlock);
			(g1->ListP).push_back(fd_obj);
			pthread_mutex_unlock(&g1->EventQlock);
			pthread_cond_broadcast(&g1->EventQ_cv);
			}
		}

	}
	
	pthread_mutex_unlock(&GlobalList_lock);
	
//____________________________________SENDING SELF RESPONSE----------------------BEGIN----------------------//	
	Flood_Elem *fd_obj2 = new Flood_Elem();
	fd_obj2->UOID = new unsigned char[20];
	fd_obj2->respUOID = new unsigned char[20];
	fd_obj2->MessageType = JNRS;
	fd_obj2->Port = fd_obj->Port;
	fd_obj2->respPort = i1->Port;
	for (int iter = 0;iter<20;iter++)
	{
		fd_obj2->UOID[iter] = fd_obj->UOID[iter];
		fd_obj2->respUOID[iter] = UOIDstr[iter];
	}
	fd_obj2->HostLocation = i1->Location;
	fd_obj2->Distance = (unsigned int)abs((int)(i1->Location) - (int)(fd_obj->HostLocation));
	int i=30;
	if(i1->TTL==0){fd_obj2->TTL=(unsigned char)i;}else{fd_obj2->TTL=(unsigned char)i1->TTL;}
				
	unsigned char *writeBuf = new unsigned char[512];
	unsigned char Reserved = (unsigned char)0;
	unsigned int DataLength = 39;
	memcpy(&writeBuf[0],&(fd_obj2->MessageType),1);
	memcpy(&writeBuf[1],fd_obj2->respUOID,20);
	memcpy(&writeBuf[21],&(fd_obj2->TTL),1);
	memcpy(&writeBuf[22],&Reserved,1);
	memcpy(&writeBuf[23],&DataLength,4);
	memcpy(&writeBuf[27],fd_obj2->UOID,20);
	memcpy(&writeBuf[47],&(fd_obj2->Distance),4);
	memcpy(&writeBuf[51],&(fd_obj2->respPort),2);
	memcpy(&writeBuf[53],&hostname,13);
	for (int it = 0;it<27 ;it++ )
	{
		if (write(mySocket,&writeBuf[it],1)==-1)
			{
			//	perror("beaconconnect: write");
				exit(1);
			}
	}
	for (int it5 = 27;it5<27+39; it5++ )
	{
		if (write(mySocket,&writeBuf[it5],1)==-1)
		{
//			perror("beaconconnect: write");
			exit(1);
		}	
	}

	//---------------------------------------------- RESET----------------------------------------------------//
	pthread_mutex_lock(&log_lock);
	FILE *Log = fopen(LogLocation.c_str(),"a");
	if(Log==NULL)
	{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
	}else{
	gettimeofday(&tim,NULL);
	fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d JNRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),fd_obj2->Port,(int)(fd_obj2->TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj2->respUOID)[pr]);}
		fprintf(Log," ");
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj2->UOID)[pr]);}
	fprintf(Log," %d %d nunki.usc.edu\n",fd_obj2->Distance,fd_obj2->respPort);
	fflush(Log);
	}
	fclose(Log);
	pthread_mutex_unlock(&log_lock);
	//---------------------------------------------------------------------------------------------------------//
//____________________________________SENDING SELF RESPONSE----------------------END----------------------//	

	while(1){
	Flood_Elem *fd_obj1 = new Flood_Elem();
	list<Flood_Elem*>* locEventQ1 = new list<Flood_Elem*>;
	fd_obj1->UOID = new unsigned char[20];
	fd_obj1->respUOID = new unsigned char[20];
	pthread_mutex_lock(&Gelem->EventQlock);
	
	if ((Gelem->ListP).size()==0)
	{
		pthread_cond_wait(&(Gelem->EventQ_cv),&(Gelem->EventQlock));
	}
	
	pthread_mutex_unlock(&Gelem->EventQlock);
	pthread_mutex_lock(&DBaseLock);	
	*locEventQ1 = Gelem->ListP;
	fd_obj1 = (Flood_Elem*)((*locEventQ1).front());
	DBase->Append((void *)fd_obj1->UOID);
	pthread_mutex_unlock(&DBaseLock);

	pthread_mutex_lock(&Gelem->EventQlock);	
	(Gelem->ListP).pop_front();
	pthread_mutex_unlock(&Gelem->EventQlock);
	if(fd_obj1->MessageType == JNRS){
	if ((int)fd_obj1->TTL !=0)
	{
		unsigned char *writeBuf1 = new unsigned char[512];
		unsigned char Reserved = (unsigned char)0;
		unsigned int DataLength = 39;
		if (fd_obj1->MessageType == JNRS)
		{
			
			memcpy(&writeBuf1[0],&(fd_obj1->MessageType),1);
			memcpy(&writeBuf1[1],fd_obj1->respUOID,20);
			memcpy(&writeBuf1[21],&(fd_obj1->TTL),1);
			memcpy(&writeBuf1[22],&Reserved,1);
			memcpy(&writeBuf1[23],&DataLength,4);
			memcpy(&writeBuf1[27],fd_obj1->UOID,20);
			memcpy(&writeBuf1[47],&(fd_obj1->Distance),4);
			memcpy(&writeBuf1[51],&(fd_obj1->respPort),2);
			memcpy(&writeBuf1[53],&hostname,13);
			for (int it = 0;it<27 ;it++ )
			{
				if (write(mySocket,&writeBuf1[it],1)==-1)
					{
//						perror("beaconconnect: write");
						exit(1);
					}
			}
			for (int it5 = 27;it5<27+39; it5++ )
			{
				if (write(mySocket,&writeBuf1[it5],1)==-1)
				{
//					perror("beaconconnect: write");
					exit(1);
				}	
			}

			//---------------------------------------------- RESET----------------------------------------------------//
			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d JNRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),fd_obj1->Port,(int)(fd_obj1->TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj1->UOID)[pr]);}
			fprintf(Log," %d nunki.usc.edu\n",fd_obj1->Port);
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);
			//---------------------------------------------------------------------------------------------------------//

			}
			pthread_mutex_lock(&PrintLock);
			pthread_mutex_unlock(&PrintLock);
		}//end if ttl !=0
		}//end if msg type == JNRS
	}//end while
	//cout<<"Inside process thread+++++++++++++++++++++++"<<endl;	exit(1);

	return 0;
}


//----------------------------------------- READ THREAD TO BE DONE -------------------------------------------------//

void *readthread(void *threadarg)
{
	//cout<<"**********************************************************8"<<endl;
	int mySocket = 0;
	int numBytes=0;
	GlobalList_Elem* Gelem = (GlobalList_Elem *)threadarg;
	mySocket = Gelem->Socket; 


	while(1){
		Catch = 1;
		unsigned char *readBuf = new unsigned char[512];

		for(int ih=0;ih<27;ih++)
		{
			if((numBytes=read(mySocket,&readBuf[ih], 1))==-1){
  //             perror("read");
						//cout<<"CheckRead1:"<<errno<<endl;
			}
		}
		if(numBytes==0)
		{
			continue;
		}
		struct HEADER h1;
		memset(&h1,0,sizeof h1);
		h1.UOID = new unsigned char[20];	   
		memcpy(&h1.MessageType,&readBuf[0],1);
		memcpy(h1.UOID,&readBuf[1],20);
		memcpy(&h1.TTL,&readBuf[21],1);
		memcpy(&h1.Reserved,&readBuf[22],1);
		memcpy(&h1.DataLength,&readBuf[23],4);

		//-------------------------------KPAV RECEIVED------------------------------------------------------//
		if (h1.MessageType==KPAV)
		{

			
			socklen_t len;
			struct sockaddr_in peer;
			len = sizeof peer;
			getpeername(mySocket, (struct sockaddr*)&peer, &len);

			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"r %10ld.%03d nunki.usc.edu_%d KPAV %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(h1.TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(h1.UOID)[pr]);}
			fprintf(Log,"\n");
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);	
		}
		//--------------------------KPAV RECEIVED END-------------------------------------------------------------//

		//-------------------------------KPAV RECEIVED------------------------------------------------------//
		if (h1.MessageType==NTFY)
		{
			Flood_Elem *ntfy_obj = new Flood_Elem();


			char* myBuf =  new char[2];
			for (int it=0;it<2;it++)
			{
				
				if ((numBytes = read(mySocket,&myBuf[it], 1))==-1){
	//			perror("read");
						//cout<<"CheckRead2:"<<errno<<endl;
				}
				//cout<<it<<endl;
				//cout<<myBuf[it]<<endl;
			}
			//cout<<numBytes<<endl;
			memcpy(&ntfy_obj->Port,&myBuf[0],2);
			//cout<<"rPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"<<ntfy_obj->Port<<endl;
			//exit(1);
			socklen_t len;
			struct sockaddr_in peer;
			len = sizeof peer;
			getpeername(mySocket, (struct sockaddr*)&peer, &len);
			//cout<<"NOTIFYYYYYYYYYYYYYYYYYYYYYY"<<ntohs(peer.sin_port)<<endl;
			pthread_mutex_lock(&GlobalList_lock);
			//cout<<"KLJLKJLDSKJFLKJSF "<<rPort<<endl;
				 list<GlobalList_Elem*>::iterator it;
			for (it =GlobalList.begin();it!=GlobalList.end();it++ )
			{
				   GlobalList_Elem *g1 = NULL;
				   g1 = (GlobalList_Elem*) (*it);
					if (g1->Port == ntfy_obj->Port)
					{
			//			cout<<"Removing: "<<g1->Port<<endl;
						GlobalList.remove(g1);
					}
			}
			//print_GlobalList();
			pthread_mutex_unlock(&GlobalList_lock);

			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"r %10ld.%03d nunki.usc.edu_%d NTFY %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(h1.TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(h1.UOID)[pr]);}
			fprintf(Log," shutdown\n");
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);	
		}
		//--------------------------KPAV RECEIVED END-------------------------------------------------------------//

		//-------------------------------------------------------------- STRS RECEIVED ON READ -------------------------BEGIN//

		if (h1.MessageType == STRS){
			//cout<<"status response received "<<endl;
			for (unsigned int it3 = 27;it3<27+h1.DataLength;it3++ )
			{
				if ((numBytes = read(mySocket,&readBuf[it3], 1))==-1)
				{
			//		perror("read");
					
				}
			}
/*			unsigned short myNeighbor=0;
			int RecordIter=0;
			int RecordIter1=0;
			unsigned short nNeighbor=0;
			memcpy(&myNeighbor,&readBuf[49],2);
			memcpy(&RecordIter,&readBuf[64],4);
            memcpy(&RecordIter1,&readBuf[64],4);
			pthread_mutex_lock(&status_lock);
			FILE* status = fopen(extfile.c_str(),"w");
    		if(status == NULL){cerr<<"Status file can not be generated. Please try again!"<<endl;}
			fprintf(status,"V -t * -v 1.0a5\n");
			fprintf(status,"n -t * -s %u -c red -i black\n",(unsigned short)(i1->Port));
			fprintf(status,"n -t * -s %u -c red -i black\n",myNeighbor);
			int myIter=68;
			while(RecordIter!=0){
            			cout<<"RecordIter: "<<RecordIter<<endl;

			memcpy(&nNeighbor,&readBuf[myIter],2);
			fprintf(status,"n -t * -s %u -c red -i black\n",nNeighbor);
			myIter=myIter+15;
			memcpy(&RecordIter,&readBuf[myIter],4);
			myIter=myIter+4;
            memset(&nNeighbor,0,2);
			}// while RecordIter

			int myIter1=68;
			while(RecordIter1!=0){
            
			memcpy(&nNeighbor,&readBuf[myIter1],2);
			fprintf(status,"l -t * -s %u -d %u -c blue\n",myNeighbor,nNeighbor);
			myIter1=myIter1+15;
			memcpy(&RecordIter1,&readBuf[myIter1],4);
			myIter1=myIter1+4;
            memset(&nNeighbor,0,2);
			}// while RecordIter
*/						
			Flood_Elem *fd_obj1 = new Flood_Elem();
	
			fd_obj1->UOID = new unsigned char[20];
			fd_obj1->respUOID = new unsigned char[20];
			fd_obj1->MessageType = h1.MessageType;
			memcpy(fd_obj1->respUOID,&readBuf[1],20);
			memcpy(fd_obj1->UOID,&readBuf[27],20);
			memcpy(&fd_obj1->respPort,&readBuf[49],2);

            //---------------------------------------------- RESET----------------------------------------------------//
			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"r %10ld.%03d nunki.usc.edu_%d STRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),fd_obj1->respPort,(int)(h1.TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj1->respUOID)[pr]);}
			fprintf(Log," ");
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj1->UOID)[pr]);}
			fprintf(Log,"\n");
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);
			//---------------------------------------------------------------------------------------------------------//

			int i=30;
			if(i1->TTL==0){fd_obj1->TTL=(unsigned char)i;}else{fd_obj1->TTL=(unsigned char)i1->TTL;}
			int memMap = 100;
			list<GlobalList_Elem*>::iterator it;
			int homeflag = 0;
			pthread_mutex_lock(&PrintLock);
			//print_GlobalList();
			pthread_mutex_unlock(&PrintLock);
			
			for (it =GlobalList.begin();it!=GlobalList.end();it++)
			{
				fd_obj1->Port = (*it)->Port;
			
					if (fd_obj1->Port == i1->Port && (*it)->Temp ==2)
					{
						homeflag=1;
					//	cout<<"GOT STRS at home node"<<endl;
						break;
					}else;
			}
		//	cout<<homeflag<<endl;
			if (homeflag!=1)
			{
				for (it =GlobalList.begin();it!=GlobalList.end();it++)
				{
					if ((*it)->Temp!=2)
					{
									
						memMap = memcmp(fd_obj1->UOID,((*it)->UOID),20);
						if (memMap == 0)
						{
							pthread_mutex_lock(&PrintLock);
							//cout<<"STRS sending Port: "<<fd_obj1->respPort<<endl;
							pthread_mutex_unlock(&PrintLock);
							if (fd_obj1->MessageType == STRS)
							{
								pthread_mutex_lock(&(*it)->EventQlock);
								((*it)->ListP).push_back(fd_obj1);
								pthread_cond_signal(&((*it)->EventQ_cv));
								pthread_mutex_unlock(&((*it)->EventQlock));
								pthread_mutex_unlock(&GlobalList_lock);

							}
						}else;
					}//end if temp	
				}//end for
			}//end homeflag
			if (homeflag == 1)
			{
		//		cout<<"Got STRS 2 at home node"<<endl;
				unsigned short myNeighbor=0;
				int RecordIter=0;
				int RecordIter1=0;
				unsigned short nNeighbor=0;
				memcpy(&myNeighbor,&readBuf[49],2);
				memcpy(&RecordIter,&readBuf[64],4);
				memcpy(&RecordIter1,&readBuf[64],4);
				pthread_mutex_lock(&status_lock);
				FILE* status = fopen(extfile.c_str(),"a");
				if(status == NULL){cerr<<"Status file can not be generated. Please try again!"<<endl;}
				fprintf(status,"n -t * -s %u -c red -i black\n",myNeighbor);
				int myIter=68;
				while(RecordIter!=0){
		//			cout<<"RecordIter: "<<RecordIter<<endl;
					memcpy(&nNeighbor,&readBuf[myIter],2);
//					pthread_mutex_lock(&nam_lock);
				//	nam->Append((void*)nNeighbor);
				//	if (duplicateNode()==1)
				//	{
						fprintf(status,"n -t * -s %u -c red -i black\n",nNeighbor);
				//	}
//					pthread_mutex_unlock(&nam_lock);
					myIter=myIter+15;
					memcpy(&RecordIter,&readBuf[myIter],4);
					myIter=myIter+4;
					memset(&nNeighbor,0,2);
				}// while RecordIter

				int myIter1=68;
				while(RecordIter1!=0){
				
					memcpy(&nNeighbor,&readBuf[myIter1],2);
					fprintf(status,"l -t * -s %u -d %u -c blue\n",myNeighbor,nNeighbor);
					myIter1=myIter1+15;
					memcpy(&RecordIter1,&readBuf[myIter1],4);
					myIter1=myIter1+4;
					memset(&nNeighbor,0,2);

				}// while RecordIter
				fclose(status);
				pthread_mutex_unlock(&status_lock);
				counter++;
//				cout<<"Count value: "<<counter<<endl;
			
//				cout<<"List size: "<<GlobalList.size()<<endl;

			
			}			


		}// if MessageType == STRS
        //-------------------------------------------------------------- STRS RECEIVED ON READ -------------------------BEGIN//  


        //-------------------------------------------------------------- STRQ RECEIVED ON  READ -----------------------------//
		if(h1.MessageType == STRQ)
		{
			if ((numBytes = read(mySocket,&readBuf[27], 1))==-1){
			//	perror("read");
			}      
			if(readBuf[27]==neighbors){
				socklen_t len;
				struct sockaddr_in peer;
				len = sizeof peer;
				getpeername(mySocket, (struct sockaddr*)&peer, &len);
				pthread_mutex_lock(&PrintLock);
		//		cout<<"Received STRQ from "<<ntohs(peer.sin_port)<<endl;
				for (int ite=0;ite<20;ite++)
				{
					//printf("%02x",(unsigned char)h1.UOID[ite]);
				}
				pthread_mutex_unlock(&PrintLock);
				Flood_Elem *fd_obj = new Flood_Elem();
				list<Flood_Elem*>* locEventQ = new list<Flood_Elem*>;
				fd_obj->UOID = new unsigned char[20];
				fd_obj->respUOID = new unsigned char[20];
				fd_obj->MessageType = h1.MessageType;
				//fd_obj->Port = msg1.HostPort;
				if(i1->TTL==0){fd_obj->TTL=(unsigned char)30;}else{fd_obj->TTL=(unsigned char)i1->TTL;}
				fd_obj->TTL = (unsigned char)min((int)fd_obj->TTL,((int)(h1.TTL)-1));
				memcpy(fd_obj->UOID,h1.UOID,20);
				DBase->Append((void *)(fd_obj->UOID));


								//---------------------------------------------- RESET----------------------------------------------------//
				pthread_mutex_lock(&log_lock);
				FILE *Log = fopen(LogLocation.c_str(),"a");
				if(Log==NULL)
				{
				cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
				}else{
				gettimeofday(&tim,NULL);
				fprintf(Log,"f %10ld.%03d nunki.usc.edu_%d STRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(h1.TTL));
				for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(h1.UOID)[pr]);}
				fprintf(Log," neighbors\n");
				fflush(Log);
				}
				fclose(Log);
				pthread_mutex_unlock(&log_lock);
				//---------------------------------------------------------------------------------------------------------//



	/*			//-------------------------TESTING-------------------------------------BEGIN//
				pthread_mutex_lock(&PrintLock);
				cout<<"JNRQ in the read thread"<<endl; 
				cout<<"Port inside read "<<fd_obj->Port<<endl;
				cout<<"TTL inside read "<<(int)fd_obj->TTL<<endl;
				cout<<"Host Location read write "<<fd_obj->HostLocation<<endl;
				cout<<"UOID inside read ";
				for(int it2=0;it2<20;it2++){
								printf("%02x",(unsigned char)(fd_obj->UOID)[it2]);
						}cout<<endl;
				pthread_mutex_unlock(&PrintLock);
				//-------------------------TESTING-------------------------------------END//
	*/       Catch =1;
				pthread_mutex_lock(&DBaseLock);
				Catch = eval_DBase();
				pthread_mutex_unlock(&DBaseLock);
		//		cout<<"ReadCatch "<<Catch<<endl;

				if (Catch == 1)
				{
					*locEventQ = Gelem->ListP;
					list<GlobalList_Elem*>::iterator it;
					pthread_mutex_lock(&GlobalList_lock);
					for (it =GlobalList.begin();it!=GlobalList.end();it++ )
					{
						GlobalList_Elem *g1 = NULL;
						g1 = (GlobalList_Elem*) (*it);
						if ((*it)!=NULL)
						{
							if (g1->Temp!=1 && g1->Temp!=2)
							{
							pthread_mutex_lock(&PrintLock);
		//					cout<<"Flooding to "<<g1->Port<<endl;
							pthread_mutex_unlock(&PrintLock);
							pthread_mutex_lock(&g1->EventQlock);
						
							for (int ite =0;ite<20;ite++ )
							{
								//printf("%02x",(unsigned char)fd_obj->UOID[ite]);
							}
							(g1->ListP).push_back(fd_obj);
							pthread_mutex_unlock(&g1->EventQlock);
							pthread_cond_broadcast(&g1->EventQ_cv);
							}
						}

					}
					pthread_mutex_unlock(&GlobalList_lock);
					int memMap = 100;
					Flood_Elem *fd_obj1 = new Flood_Elem();
					fd_obj1->UOID = new unsigned char[20];
					fd_obj1->respUOID = new unsigned char[20];

					if(i1->TTL==0){fd_obj1->TTL=(unsigned char)30;}else{fd_obj1->TTL=(unsigned char)i1->TTL;}
					fd_obj1->TTL = (unsigned char)min((int)fd_obj1->TTL,((int)(h1.TTL)-1));
					fd_obj1->MessageType = STRS;
					fd_obj1->respPort = i1->Port;
					memcpy(fd_obj1->respUOID,(GetUOID(node_instance_id,"msg")),20);
					memcpy(fd_obj1->UOID,h1.UOID,20);
					
					
					memMap = memcmp(fd_obj1->respUOID,fd_obj1->UOID,20);
					if (memMap!=0)
					{
		//				cout<<"Sending STRS back to "<<ntohs(peer.sin_port)<<endl;
						pthread_mutex_lock(&Gelem->EventQlock);
						(Gelem->ListP).push_back(fd_obj1);
						pthread_cond_signal(&Gelem->EventQ_cv);		
						pthread_mutex_unlock(&Gelem->EventQlock);
					}else;
				}//END IF CATCH

			   }// END IF neighbors


		}//END IF STRQ
		//-------------------------------------------------------- END STRQ READ -----------------------------------------//
		
		if(h1.MessageType == JNRQ)
		{
/*			//-------------------------TESTING-------------------------------------BEGIN//
			
			pthread_mutex_lock(&PrintLock);
			cout<<"Join received on read thread"<<endl;
			cout<<"TTL inside read "<<(int)h1.TTL<<endl;
			cout<<"UOID inside read ";
			for(int it2=0;it2<20;it2++){
							printf("%02x",(unsigned char)(h1.UOID)[it2]);
					}cout<<endl;
			cout<<"DataLength inside read: "<<h1.DataLength<<endl;
			cout<<"Reserved inside read: "<<(int)h1.Reserved<<endl;
			pthread_mutex_unlock(&PrintLock);

			//-------------------------TESTING-------------------------------------END//
*/			
			struct JOIN_MSG msg1;
			memset(&msg1,0,sizeof msg1);
			msg1.HostName = new char[13];
			for (unsigned int it3 = 27;it3<27+h1.DataLength;it3++ )
			{
				if ((numBytes = read(mySocket,&readBuf[it3], 1))==-1)
				{
			//		perror("read");
				}
			}			
			memcpy(&msg1.HostLocation,&readBuf[27],4);
			memcpy(&msg1.HostPort,&readBuf[31],2);
			memcpy(msg1.HostName,&readBuf[33],13);

            
            //---------------------------------------------- RESET----------------------------------------------------//
			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"r %10ld.%03d nunki.usc.edu_%d JNRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),msg1.HostPort,(int)(h1.TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(h1.UOID)[pr]);}
			fprintf(Log," %d nunki.usc.edu\n",msg1.HostPort);
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);
			//---------------------------------------------------------------------------------------------------------//

			Flood_Elem *fd_obj = new Flood_Elem();
			list<Flood_Elem*>* locEventQ = new list<Flood_Elem*>;
			fd_obj->UOID = new unsigned char[20];
			fd_obj->respUOID = new unsigned char[20];
			fd_obj->MessageType = h1.MessageType;
			fd_obj->Port = msg1.HostPort;
			fd_obj->HostLocation = msg1.HostLocation;
			fd_obj->TTL = h1.TTL;
			fd_obj->TTL = (unsigned char)(((int)fd_obj->TTL)- 1);
			memcpy(fd_obj->UOID,h1.UOID,20);
			DBase->Append((void *)(fd_obj->UOID));


/*			//-------------------------TESTING-------------------------------------BEGIN//
			pthread_mutex_lock(&PrintLock);
			cout<<"JNRQ in the read thread"<<endl; 
			cout<<"Port inside read "<<fd_obj->Port<<endl;
			cout<<"TTL inside read "<<(int)fd_obj->TTL<<endl;
			cout<<"Host Location read write "<<fd_obj->HostLocation<<endl;
			cout<<"UOID inside read ";
			for(int it2=0;it2<20;it2++){
							printf("%02x",(unsigned char)(fd_obj->UOID)[it2]);
					}cout<<endl;
			pthread_mutex_unlock(&PrintLock);
			//-------------------------TESTING-------------------------------------END//
*/            
			Catch = eval_DBase();
			if (Catch == 1)
			{
				*locEventQ = Gelem->ListP;
				list<GlobalList_Elem*>::iterator it;
				pthread_mutex_lock(&GlobalList_lock);
				for (it =GlobalList.begin();it!=GlobalList.end();it++ )
				{
					GlobalList_Elem *g1 = NULL;
					g1 = (GlobalList_Elem*) (*it);
					if ((*it)!=NULL)
					{
						if (g1->Temp!=1 && g1->Temp!=2)
						{
						
						pthread_mutex_lock(&PrintLock);
						pthread_mutex_unlock(&PrintLock);
						pthread_mutex_lock(&g1->EventQlock);
						(g1->ListP).push_back(fd_obj);
						pthread_mutex_unlock(&g1->EventQlock);
						pthread_cond_broadcast(&g1->EventQ_cv);
						}
					}

				}
				pthread_mutex_unlock(&GlobalList_lock);
				Flood_Elem *fd_obj1 = new Flood_Elem();
				fd_obj1->UOID = new unsigned char[20];
				fd_obj1->respUOID = new unsigned char[20];
				fd_obj1->MessageType = JNRS;
				fd_obj1->Port = msg1.HostPort;
				fd_obj1->respPort = i1->Port;
				memcpy(fd_obj1->respUOID,(GetUOID(node_instance_id,"msg")),20);
				memcpy(fd_obj1->UOID,h1.UOID,20);
				
				fd_obj1->HostLocation = i1->Location;
				fd_obj1->Distance = (unsigned int)abs((int)(i1->Location) - (int)(fd_obj->HostLocation));
				
				if(i1->TTL==0){fd_obj1->TTL=(unsigned char)30;}else{fd_obj1->TTL=(unsigned char)i1->TTL;}
				fd_obj1->TTL = (unsigned char)min((int)fd_obj1->TTL,((int)(h1.TTL)-1));

				
				pthread_mutex_lock(&Gelem->EventQlock);
				*locEventQ = Gelem->ListP;
				(Gelem->ListP).push_back(fd_obj1);
				pthread_cond_signal(&Gelem->EventQ_cv);

				pthread_mutex_unlock(&Gelem->EventQlock);

				
	
			}//end IF CATCH == 1
		}//END IF MSG TYPE = JNRQ 

		
		if (h1.MessageType == JNRS)
		{
			struct JOIN_RES respMsg1;
			memset(&respMsg1,0,sizeof respMsg1);
			respMsg1.UOID = new unsigned char[20];
			respMsg1.HostName = new char[13];
			unsigned int it9 = 0;
			for (unsigned int it3 = 27;it3<27+39;it3++ )
			{
				if ((numBytes = read(mySocket,&readBuf[it3], 1))==-1)
				{
			//		perror("read");
					
				}
				it9 = it3;
			}
			memcpy(respMsg1.UOID,&readBuf[27],20);
			memcpy(&respMsg1.Distance,&readBuf[47],4);
			memcpy(&respMsg1.HostPort,&readBuf[51],2);
			memcpy(&respMsg1.HostName,&readBuf[53],13);


			//---------------------------------------------- RESET----------------------------------------------------//
			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"r %10ld.%03d nunki.usc.edu_%d JNRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),respMsg1.HostPort,(int)(h1.TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(h1.UOID)[pr]);}
			fprintf(Log," ");
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(respMsg1.UOID)[pr]);}
			fprintf(Log," %d %d nunki.usc.edu\n",respMsg1.Distance,respMsg1.HostPort);
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);
			//---------------------------------------------------------------------------------------------------------//


			Flood_Elem *fd_obj1 = new Flood_Elem();
	
			fd_obj1->UOID = new unsigned char[20];
			fd_obj1->respUOID = new unsigned char[20];
			int memMap = 100;
			list<GlobalList_Elem*>::iterator it;

			for (it =GlobalList.begin();it!=GlobalList.end();it++ )
			{
				if ((*it)->Temp!=2)
				{
				
				memMap = memcmp(respMsg1.UOID,((*it)->UOID),20);
				if (memMap == 0)
				{
					fd_obj1->MessageType = h1.MessageType;
					fd_obj1->Port = (*it)->Port;
					fd_obj1->respPort = respMsg1.HostPort;
					for (int iter = 0;iter<20;iter++)
					{
						fd_obj1->respUOID[iter] = h1.UOID[iter];
						fd_obj1->UOID[iter] = respMsg1.UOID[iter];
					}
					fd_obj1->HostLocation = i1->Location;
					fd_obj1->Distance = respMsg1.Distance;
					if(i1->TTL==0){fd_obj1->TTL=(unsigned char)30;}else{fd_obj1->TTL=(unsigned char)i1->TTL;}
					fd_obj1->TTL = (unsigned char)min((int)fd_obj1->TTL,((int)(h1.TTL)-1));
					if (fd_obj1->MessageType == JNRS)
					{
						pthread_mutex_lock(&(*it)->EventQlock);
						((*it)->ListP).push_back(fd_obj1);
						pthread_cond_signal(&((*it)->EventQ_cv));
						pthread_mutex_unlock(&((*it)->EventQlock));
						pthread_mutex_unlock(&GlobalList_lock);

					}
					
				}else;
				}
			}//end for loop
			
		}//end else jnrs
		
	}//end while

	
	pthread_exit(NULL);
}
//----------------------------------------- READ THREAD TO BE END -------------------------------------------------//


//----------------------------------------- WRITE THREAD BEGIN -----------------------------------------------------//

void *writethread(void *threadarg)
{
		//cout<<"***********************************************"<<endl;
	int mySocket;
	GlobalList_Elem* Gelem = (GlobalList_Elem *)threadarg;
	mySocket = Gelem->Socket;
	socklen_t len;
	struct sockaddr_in peer;
	len = sizeof peer;
	getpeername(mySocket, (struct sockaddr*)&peer, &len);
	
	while(1){
	Flood_Elem *fd_obj = new Flood_Elem();
	list<Flood_Elem*>* locEventQ = new list<Flood_Elem*>;
	fd_obj->UOID = new unsigned char[20];
	fd_obj->respUOID = new unsigned char[20];
	pthread_mutex_lock(&Gelem->EventQlock);
	if ((Gelem->ListP).size()==0)
	{
		pthread_cond_wait(&Gelem->EventQ_cv,&Gelem->EventQlock);
	}
	pthread_mutex_unlock(&Gelem->EventQlock);
	pthread_mutex_lock(&DBaseLock);	
	*locEventQ = Gelem->ListP;
	fd_obj = (Flood_Elem*)((*locEventQ).front());
	DBase->Append((void *)(fd_obj->UOID));
	pthread_mutex_unlock(&DBaseLock);
	pthread_mutex_lock(&Gelem->EventQlock);	
	(Gelem->ListP).pop_front();
	pthread_mutex_unlock(&Gelem->EventQlock);


	if (fd_obj->MessageType==NTFY)
	{
			unsigned char *writeBuf = new unsigned char[512];
			unsigned char Reserved = (unsigned char)0;
			int DataLength = 1;
			struct JOIN_MSG msg;
			memset(&msg,0,sizeof msg);
				msg.HostPort=i1->Port;
			memcpy(&writeBuf[0],&(fd_obj->MessageType),1);
			memcpy(&writeBuf[1],fd_obj->UOID,20);
			memcpy(&writeBuf[21],&(fd_obj->TTL),1);
			memcpy(&writeBuf[22],&Reserved,1);
			memcpy(&writeBuf[23],&DataLength,4);
			memcpy(&writeBuf[27],&msg.HostPort,2);
			
		//	cout<<"jlksdajflkjalskfdj "<<msg.HostPort<<endl;
			for (int it = 0;it<29 ;it++)
			{
				if (write(mySocket,&writeBuf[it],1)==-1)
					{
						//perror("beaconconnect: write");
		//				cout<<"CheckWrite1:"<<errno<<endl; 
				//		exit(1);
					}

			}

/*			for (int it=27;it<29;it++)
			{
				if (write(mySocket,&writeBuf[it],1)==-1)
				{
			
						cout<<"CheckWrite1:"<<errno<<endl;
				}
			}
*/			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d NTFY %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(fd_obj->TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->UOID)[pr]);}
			fprintf(Log," ");
			fprintf(Log,"shutdown\n");
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);

	//		cout<<"Sent NTFY"<<endl;		
		
	}
	if (fd_obj->MessageType==KPAV){
			
			unsigned char *writeBuf = new unsigned char[512];
			unsigned char Reserved = (unsigned char)0;
			unsigned int DataLength = 0;
			memcpy(&writeBuf[0],&(fd_obj->MessageType),1);
			memcpy(&writeBuf[1],fd_obj->UOID,20);
			memcpy(&writeBuf[21],&(fd_obj->TTL),1);
			memcpy(&writeBuf[22],&Reserved,1);
			memcpy(&writeBuf[23],&DataLength,4);			
			for (int it = 0;it<27 ;it++ )
			{
				if (write(mySocket,&writeBuf[it],1)==-1)
					{
				//		perror("beaconconnect: write");///call send_check function
	//					cout<<"CheckWrite2:"<<errno<<endl;
//						exit(1);
					}
			}	
			pthread_mutex_lock(&log_lock);
			FILE *Log = fopen(LogLocation.c_str(),"a");
			if(Log==NULL)
			{
			cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
			}else{
			gettimeofday(&tim,NULL);
			fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d KPAV %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(fd_obj->TTL));
			for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->UOID)[pr]);}
			fprintf(Log,"\n");
			fflush(Log);
			}
			fclose(Log);
			pthread_mutex_unlock(&log_lock);
	//		cout<<"Sent KPAV"<<endl;
		
	}
	//------------------------------------------------------------------------------STRS -----------------------------BEGIN-------//

	if(fd_obj->MessageType==STRS)
	{
	    struct HEADER sHeader;
		short HostInfoLength = 15;
		int RecordLength = 15;
		int RecordZero = 0;
		unsigned short HostPort = i1->Port;

		sHeader.MessageType = STRS;
        sHeader.UOID = new unsigned char[20];
		for(int it2=0;it2<20;it2++){
					sHeader.UOID[it2]=fd_obj->respUOID[it2];
				}
		
		sHeader.TTL = (unsigned char)(fd_obj->TTL);
		sHeader.Reserved = (unsigned char)0;
		sHeader.DataLength = 20+2+2+13+(19*(GlobalList.size()))+1;


		unsigned char* StatusMsg = new unsigned char[512];
		memcpy(&StatusMsg[0],&sHeader.MessageType,1);
		memcpy(&StatusMsg[1],sHeader.UOID,20);
		memcpy(&StatusMsg[21],&sHeader.TTL,1);
		memcpy(&StatusMsg[22],&sHeader.Reserved,1);
		memcpy(&StatusMsg[23],&sHeader.DataLength,4);

		memcpy(&StatusMsg[27],fd_obj->respUOID,20);
		memcpy(&StatusMsg[47],&HostInfoLength,2);
		memcpy(&StatusMsg[49],&HostPort,2);
		memcpy(&StatusMsg[51],&hostname,13);
    
	   //iterate here for record length and data
       int RecordIter=64;
	   list<GlobalList_Elem*>::iterator it;
       pthread_mutex_lock(&GlobalList_lock);

	   for (it =GlobalList.begin();it!=GlobalList.end();it++ )
	   {
			   GlobalList_Elem *g1 = NULL;
			   g1 = (GlobalList_Elem*) (*it);
			   if ((*it)!=NULL)
			   {
				      // i=64+i;
//					  cout<<"Neighbor Port: "<<(*it)->Port<<endl;
				       memcpy(&StatusMsg[RecordIter],&RecordLength,4);
					   memcpy(&StatusMsg[RecordIter+4],&((*it)->Port),2);
					   memcpy(&StatusMsg[RecordIter+6],&hostname,13);
					   RecordIter=RecordIter+19;
			   }

	   }
	   pthread_mutex_unlock(&GlobalList_lock);
	   memcpy(&StatusMsg[RecordIter],&RecordZero,4);

	   ////	
	   //----------------------------------------- SENDING MESSAGE ------------------------------------- BEGIN--//
	   for (unsigned int it = 0;it<27 ;it++ )
		{
				if (write(mySocket,&StatusMsg[it],1)==-1)
					{
					//	perror("beaconconnect: write");
						exit(1);
					}
		}

		for (unsigned int it5 = 27;it5<27+sHeader.DataLength; it5++ )
		{
				if (write(mySocket,&StatusMsg[it5],1)==-1)
				{
				//	perror("beaconconnect: write");
					exit(1);
				}	
		}

				//---------------------------------------------- RESET----------------------------------------------------//
		pthread_mutex_lock(&log_lock);
		FILE *Log = fopen(LogLocation.c_str(),"a");
		if(Log==NULL)
		{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
		}else{
		gettimeofday(&tim,NULL);
		fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d STRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(sHeader.TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(sHeader.UOID)[pr]);}
		fprintf(Log," ");
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->respUOID)[pr]);}
		fprintf(Log,"\n");
		fflush(Log);
		}
		fclose(Log);
		pthread_mutex_unlock(&log_lock);
		//---------------------------------------------------------------------------------------------------------//

	   //----------------------------------------- SENDING MESSAGE ------------------------------------- END---//
		pthread_mutex_lock(&PrintLock);
	//	print_GlobalList();
	//	cout<<"Sent STRS to "<<ntohs(peer.sin_port)<<endl;
/*		cout<<"fd UOID ";
		for(int k=0;k<20;k++)
		{
          printf("%02x",(unsigned char)(fd_obj->UOID)[k]);
		}cout<<endl;
		cout<<"res UOID";
		for(int k=0;k<20;k++)
		{
          printf("%02x",(unsigned char)(fd_obj->respUOID)[k]);
		}cout<<endl;
*/		pthread_mutex_unlock(&PrintLock);
		//exit(1);
	}//if strs
 	//------------------------------------------------------------------------------STRS -----------------------------END---------//

	//------------------------------------------------------------------------------STRQ ------------------------------BEGIN------//

	if(fd_obj->MessageType==STRQ)
	{
		struct HEADER sHeader;

		sHeader.MessageType = STRQ;
        sHeader.UOID = new unsigned char[20];
		for(int it2=0;it2<20;it2++){
					sHeader.UOID[it2]=fd_obj->UOID[it2];
				}
		
		sHeader.TTL = (unsigned char)(fd_obj->TTL);
		sHeader.Reserved = (unsigned char)0;
		sHeader.DataLength = 1;

		struct STATUS_MSG sMsg;
		sMsg.StatusType=neighbors;

		//if(fd_obj->flag==1){sMsg.StatusType=neighbors;}else{sMsg.StatusType=files;}

		unsigned char* StatusMsg = new unsigned char[512];
		memcpy(&StatusMsg[0],&sHeader.MessageType,1);
		memcpy(&StatusMsg[1],sHeader.UOID,20);
		memcpy(&StatusMsg[21],&sHeader.TTL,1);
		memcpy(&StatusMsg[22],&sHeader.Reserved,1);
		memcpy(&StatusMsg[23],&sHeader.DataLength,4);
		memcpy(&StatusMsg[27],&sMsg.StatusType,1);

		for (int it = 0;it<27 ;it++ )
			{
				if (write(mySocket,&StatusMsg[it],1)==-1)
					{
					//	perror("beaconconnect: write");
						exit(1);
					}
			}
			for (int it5 = 27;it5<28; it5++ )
			{
				if (write(mySocket,&StatusMsg[it5],1)==-1)
				{
		//			perror("beaconconnect: write");
					exit(1);
				}	
			}

			
	    //---------------------------------------------- RESET----------------------------------------------------//
		pthread_mutex_lock(&log_lock);
		FILE *Log = fopen(LogLocation.c_str(),"a");
		if(Log==NULL)
		{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
		}else{
		gettimeofday(&tim,NULL);
		fprintf(Log,"f %10ld.%03d nunki.usc.edu_%d STRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(sHeader.TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(sHeader.UOID)[pr]);}
		fprintf(Log," neighbors\n");
		fflush(Log);
		}
		fclose(Log);
		pthread_mutex_unlock(&log_lock);
		//---------------------------------------------------------------------------------------------------------//
			pthread_mutex_lock(&PrintLock);
	//		cout<<"STRQ UOID: ";
			for(int it2=0;it2<20;it2++){
						//printf("%02x",(unsigned char)(fd_obj->UOID)[it2]);
				}
				//cout<<endl;
				
		//	cout<<"STRQ flooded to "<<Gelem->Port<<endl;
		
			pthread_mutex_unlock(&PrintLock);


	}
		
    //------------------------------------------------------------------------------STRQ ------------------------------END--------//	
	if(fd_obj->MessageType==JNRQ)
	{
/*			
	//-----------------------------TESTING--------------------------BEGIN------//
		pthread_mutex_lock(&PrintLock);
		cout<<"JNRQ in the write thread"<<endl; 
		cout<<"Port inside write "<<fd_obj->Port<<endl;
		cout<<"TTL inside write "<<(int)fd_obj->TTL<<endl;
		cout<<"Host Location inside write "<<fd_obj->HostLocation<<endl;
		cout<<"UOID inside write ";
		for(int it2=0;it2<20;it2++){
						printf("%02x",(unsigned char)(fd_obj->UOID)[it2]);
				}cout<<endl;
		pthread_mutex_unlock(&PrintLock);
		//-----------------------------TESTING--------------------------END------//
*/		
		if ((int)fd_obj->TTL !=0)
		{

			unsigned char *writeBuf = new unsigned char[512];
			unsigned char Reserved = (unsigned char)0;
			unsigned int DataLength = 19;
			memcpy(&writeBuf[0],&(fd_obj->MessageType),1);
			memcpy(&writeBuf[1],fd_obj->UOID,20);
			memcpy(&writeBuf[21],&(fd_obj->TTL),1);
			memcpy(&writeBuf[22],&Reserved,1);
			memcpy(&writeBuf[23],&DataLength,4);
			memcpy(&writeBuf[27],&(fd_obj->HostLocation),4);
			memcpy(&writeBuf[31],&(fd_obj->Port),2);
			memcpy(&writeBuf[33],&hostname,13);
			
			for (int it = 0;it<27 ;it++ )
			{
				if (write(mySocket,&writeBuf[it],1)==-1)
					{
				//		perror("beaconconnect: write");
						exit(1);
					}
			}
			for (int it5 = 27;it5<27+19; it5++ )
			{
				if (write(mySocket,&writeBuf[it5],1)==-1)
				{
			//		perror("beaconconnect: write");
					exit(1);
				}	
			}
        //---------------------------------------------- RESET----------------------------------------------------//
		pthread_mutex_lock(&log_lock);
		FILE *Log = fopen(LogLocation.c_str(),"a");
		if(Log==NULL)
		{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
		}else{
		gettimeofday(&tim,NULL);
		fprintf(Log,"f %10ld.%03d nunki.usc.edu_%d JNRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(fd_obj->TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->UOID)[pr]);}
		fprintf(Log," %d nunki.usc.ed\n",fd_obj->Port);
		fflush(Log);
		}
		fclose(Log);
		pthread_mutex_unlock(&log_lock);
		//---------------------------------------------------------------------------------------------------------//
          

		}else{
		//	cout<<"TTL is ZERO"<<endl; //exit(1);
		}
	}//END IF MSG TYPE = JNRQ
	else if(fd_obj->MessageType == JNRS){
		if ((int)fd_obj->TTL !=0)
		{

			unsigned char *writeBuf1 = new unsigned char[512];
			unsigned char Reserved = (unsigned char)0;

			unsigned int DataLength = 39;
						
			memcpy(&writeBuf1[0],&(fd_obj->MessageType),1);
			memcpy(&writeBuf1[1],fd_obj->respUOID,20);
			memcpy(&writeBuf1[21],&(fd_obj->TTL),1);
			memcpy(&writeBuf1[22],&Reserved,1);
			memcpy(&writeBuf1[23],&DataLength,4);
			memcpy(&writeBuf1[27],fd_obj->UOID,20);
			memcpy(&writeBuf1[47],&(fd_obj->Distance),4);
			memcpy(&writeBuf1[51],&(fd_obj->respPort),2);
			memcpy(&writeBuf1[53],&hostname,13);
			for (int it = 0;it<27 ;it++ )
			{
				if (write(mySocket,&writeBuf1[it],1)==-1)
					{
						//perror("beaconconnect: write");
						exit(1);
					}
			}
			for (int it5 = 27;it5<27+39; it5++ )
			{
				if (write(mySocket,&writeBuf1[it5],1)==-1)
				{
			//		perror("beaconconnect: write");
					exit(1);
				}	
			}

	    //---------------------------------------------- RESET----------------------------------------------------//
		pthread_mutex_lock(&log_lock);
		FILE *Log = fopen(LogLocation.c_str(),"a");
		if(Log==NULL)
		{
		cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
		}else{
		gettimeofday(&tim,NULL);
		fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d JNRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(fd_obj->TTL));
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->respUOID)[pr]);}
		fprintf(Log," ");
		for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",(fd_obj->UOID)[pr]);}
		fprintf(Log," %d %d nunki.usc.ed\n",fd_obj->Distance,fd_obj->respPort);
		fflush(Log);
		}
		fclose(Log);
		pthread_mutex_unlock(&log_lock);
		//---------------------------------------------------------------------------------------------------------//
		}
		}	
	}//end while
	pthread_exit(NULL);
}
//----------------------------------------- WRITE THREAD END ----------------------------------------------------//


